﻿using System;
using System.Drawing;
using System.Xml;
using System.Collections;
using TextEditor.TextDocument.Document;

namespace TextEditor
{


    public class ZYTextChar : ZYTextElement
    {
        internal Color intForeColor = Color.Black;
        private char myChar = ' ';
        private System.Drawing.Font myFont = null;

        public ZYTextChar()
        {
        }

        public bool AppendToXML(XmlElement myElement)
        {
            XmlText newChild = myElement.OwnerDocument.CreateTextNode(this.myChar.ToString());
            myElement.AppendChild(newChild);
            return true;
        }

        public override bool CanBeLineEnd()
        {
            return ("([{\x00b7‘“〈《「『【〔〖（．［｛￡￥".IndexOf(this.myChar) < 0);
        }

        public override bool CanBeLineHead()
        {
            return ("!),.:;?]}\x00a8\x00b7ˇˉ―‖’”…∶、。〃々〉》」』】〕〗！＂＇），．：；？］｀｜｝～￠\"'".IndexOf(this.myChar) < 0);
        }

        internal void ClearFont()
        {
            this.myFont = null;
        }

        public static ZYTextChar Create(char c)
        {
            ZYTextChar ch;
            if (c == '\t')
            {
                ch = new ZYTextCharTab();
            }
            else
            {
                ch = new ZYTextChar();
            }
            ch.Char = c;
            return ch;
        }

        public override bool FromXML(XmlElement myElement)
        {
            if (myElement == null)
            {
                return false;
            }
            string innerText = myElement.InnerText;
            if ((innerText == null) || (innerText.Length == 0))
            {
                innerText = " ";
            }
            this.myChar = innerText[0];
            return base.FromXML(myElement);
        }

        public override string GetXMLName()
        {
            return "span";
        }

        public bool IsSymbol()
        {
            return (("!),.:;?]}\x00a8\x00b7ˇˉ―‖’”…∶、。〃々〉》」』】〕〗！＂＇），．：；？］｀｜｝～￠\"'".IndexOf(this.myChar) >= 0) || ("([{\x00b7‘“〈《「『【〔〖（．［｛￡￥".IndexOf(this.myChar) >= 0));
        }

        public bool IsChina()
        {
            return ("，。！？；：、".IndexOf(this.myChar) >= 0);
        }

        public override bool RefreshSize()
        {
            bool sup = this.Sup;
            bool sub = this.Sub;
            SizeF ef;
            if (this.myFont == null)
            {
                this.myFont = base.myOwnerDocument.View._CreateFont(this.FontName, (Sub || Sup) ? ((float)((int)(this.FontSize * 0.6))) : this.FontSize, this.FontBold, this.FontItalic, false);
            }

            if ((myChar == ' ') || (myChar == '\b'))
            {
                ef = base.myOwnerDocument.View.Graph.MeasureString(this.myChar.ToString(), this.myFont, 1000, StringFormat.GenericDefault);
            }
            else
            {
                ef = base.myOwnerDocument.View.Graph.MeasureString(this.myChar.ToString(), this.myFont, 1000, StringFormat.GenericTypographic);
            }
            if (this.myChar == '\t')
            {
                base.intWidth = base.myOwnerDocument.View.GetTabWidth(this.RealLeft);
            }
            else if (this.myChar == ' ')
            {
                base.intWidth = 8;
            }
            else
            {
                if (base.OwnerDocument.isEnglishNum(this.Char))
                {
                    base.intWidth = Convert.ToInt32(ef.Width);
                }
                else
                    base.intWidth = Convert.ToInt32(ef.Width);
            }
            base.intHeight = (int)this.myFont.GetHeight();
            if (sup || sub)
            {
                this.Height = (int)(base.intHeight * 1.9);
            }
            return true;
        }

        public override bool RefreshView()
        {
            if (base.myOwnerDocument.isNeedDraw(this))
            {
                //if (char.IsWhiteSpace(this.myChar))
                //{
                //    return true;
                //}

                int realLeft = this.RealLeft;
                int realTop = this.RealTop;
                bool sub = this.Sub;
                bool sup = this.Sup;
                if (this.myFont == null)
                {
                    this.myFont = base.myOwnerDocument.View._CreateFont(this.FontName, (sub || sup) ? ((float)((int)(this.FontSize * 0.6))) : this.FontSize, this.FontBold, this.FontItalic, this.FontUnderLine);
                }
                if (sub || sup)
                {
                    SizeF CharSize = base.myOwnerDocument.View.Graph.MeasureString(this.myChar.ToString(), this.myFont, 0x3e8, StringFormat.GenericTypographic);
                    base.myOwnerDocument.View.DrawChar(this.myChar, this.myFont, this.ForeColor, realLeft, sup ? realTop : ((realTop + this.Height) - ((int)CharSize.Height)));
                }
                else
                {
                    base.myOwnerDocument.View.DrawChar(this.myChar, this.myFont, this.ForeColor, realLeft, realTop);
                    if (this.FontUnderLine)
                    {
                        base.OwnerDocument.View.DrawLine(Pens.Black, realLeft, realTop + this.intHeight - 1, realLeft + this.intWidth, realTop + this.intHeight - 1);
                    }
                }
            }
            return true;
        }

        public override string ToZYString()
        {
            return this.myChar.ToString();
        }

        public override string ToString()
        {
            return ("ZYTextChar:" + this.myChar.ToString());
        }

        public override bool ToXML(XmlElement myElement)
        {
            if (myElement != null)
            {
                switch (base.myOwnerDocument.Info.SaveMode)
                {
                    case 0:
                        {
                            XmlText newChild = myElement.OwnerDocument.CreateTextNode(this.myChar.ToString());
                            myElement.AppendChild(newChild);
                            base.myAttributes.ToXML(myElement);
                            goto Label_0086;
                        }
                    case 1:
                        {
                            XmlText text2 = myElement.OwnerDocument.CreateTextNode(this.myChar.ToString());
                            myElement.AppendChild(text2);
                            return true;
                        }
                    case 2:
                        goto Label_0086;
                }
            }
            return false;
        Label_0086:
            return true;
        }

        public override void UpdateAttrubute()
        {
            this.intForeColor = base.myAttributes.GetColor("forecolor");
            this.ClearFont();
            base.UpdateAttrubute();
        }

        public char Char
        {
            get
            {
                return this.myChar;
            }
            set
            {
                this.myChar = value;
            }
        }

        public override System.Drawing.Font Font
        {
            get
            {
                if (this.myFont == null)
                {
                    this.myFont = base.myOwnerDocument.View._CreateFont(this.FontName, this.FontSize, this.FontBold, this.FontItalic, this.FontUnderLine);
                }
                return this.myFont;
            }
            set
            {
                if (value == null)
                {
                    this.myFont = null;
                    this.FontName = base.FontName;
                    this.ForeColor = base.ForeColor;
                    this.FontSize = base.FontSize;
                    this.FontBold = base.FontBold;
                    this.FontItalic = base.FontItalic;
                }
                else
                {
                    this.FontName = value.Name;
                    this.FontSize = value.Size;
                    this.ForeColor = base.ForeColor;
                    this.FontBold = value.Bold;
                    this.FontItalic = value.Italic;
                }
            }
        }

        public override bool FontBold
        {
            get
            {
                return base.myAttributes.GetBool("fontbold");
            }
            set
            {
                base.myAttributes.SetValue("fontbold", value);
                this.myFont = null;
            }
        }

        public override bool FontItalic
        {
            get
            {
                return base.myAttributes.GetBool("fontitalic");
            }
            set
            {
                base.myAttributes.SetValue("fontitalic", value);
                this.myFont = null;
            }
        }

        public override string FontName
        {
            get
            {
                return base.myAttributes.GetString("fontname");
            }
            set
            {
                base.myAttributes.SetValue("fontname", value);
                this.myFont = null;
            }
        }

        public override float FontSize
        {
            get
            {
                if (base.Attributes.Contains("fontsize"))
                {
                    return base.myAttributes.GetFloat("fontsize");
                }
                else
                {
                    return base.OwnerDocument.Info.defaultFontSize;
                }
            }
            set
            {
                base.myAttributes.SetValue("fontsize", value);
                this.myFont = null;
            }
        }

        public override bool FontUnderLine
        {
            get
            {
                return base.myAttributes.GetBool("fontunderline");
            }
            set
            {
                base.myAttributes.SetValue("fontunderline", value);
            }
        }

        public override Color ForeColor
        {
            get
            {
                //if (base.myParent != null && base.myParent.Locked)
                //{
                //    return ZYTextConst.LockedForeColor;
                //}
                return this.intForeColor;
            }
            set
            {
                base.myAttributes.SetValue("forecolor", value);
                this.intForeColor = value;
            }
        }

        public override ZYTextDocument OwnerDocument
        {
            get
            {
                return base.OwnerDocument;
            }
            set
            {
                base.OwnerDocument = value;
                this.myFont = null;
            }
        }

        /***
         * 下标
         */
        public bool Sub
        {
            get
            {
                return base.myAttributes.GetBool("sub");
            }
            set
            {
                base.myAttributes.SetValue("sub", value);
                if (value && Sup)
                {
                    Sup = false;
                }
                this.myFont = null;
            }
        }

        /***
         * 上标
         */
        public bool Sup
        {
            get
            {
                return base.myAttributes.GetBool("sup");
            }
            set
            {
                base.myAttributes.SetValue("sup", value);
                if (value && Sub)
                {
                    Sub = false;
                }
                this.myFont = null;
            }
        }
    }
}

